package com.cnswhy.cloud.server.comsumer.consumer;

import com.alibaba.fastjson.JSON;
import com.cnswhy.cloud.common.core.mybatis.conditions.Wraps;
import com.cnswhy.cloud.common.core.utils.SystemClockUtil;
import com.cnswhy.cloud.common.logging.uitls.MDCUtil;
import com.cnswhy.cloud.common.rabbitmq.service.MessageService;
import com.cnswhy.cloud.common.redis.annotation.RedisLock;
import com.cnswhy.cloud.common.redis.service.IdGeneratorService;
import com.cnswhy.cloud.server.common.entity.constant.AmqpExchange;
import com.cnswhy.cloud.server.common.entity.mq.SpellFinishedMsg;
import com.cnswhy.cloud.server.common.entity.mq.SpellMsg;
import com.cnswhy.cloud.server.comsumer.event.SpellEvent;
import com.cnswhy.cloud.server.core.entity.SpellInfo;
import com.cnswhy.cloud.server.core.entity.SpellOrder;
import com.cnswhy.cloud.server.core.entity.SpellPrice;
import com.cnswhy.cloud.server.core.oem.OemService;
import com.cnswhy.cloud.server.core.service.CustomerWalletService;
import com.cnswhy.cloud.server.core.service.SpellInfoService;
import com.cnswhy.cloud.server.core.service.spell.SpellOrderService;
import com.cnswhy.cloud.server.core.service.spell.SpellPriceService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

import static com.cnswhy.cloud.common.core.context.BaseContextConstants.LOG_TRACE_ID;

@Component
@Slf4j
public class SpellConsumer implements SpellEvent {
    @Autowired
    CustomerWalletService customerWalletService;
    @Autowired
    SpellOrderService spellOrderService;
    @Autowired
    SpellPriceService spellPriceService;
    @Autowired
    SpellInfoService spellInfoService;
    @Autowired
    IdGeneratorService idGeneratorService;
    @Autowired
    MessageService messageService;
    @Autowired
    OemService oemService;

    @Override
    @RedisLock(name = "spell")
    public void spell(SpellMsg spellMsg) {

        if (oemService.isChaoRenGou()) {
            spellChaoRenHaiGouNew(spellMsg);
        } else {
            spellDefault(spellMsg);
        }
    }
    @Override
    @RedisLock(name = "chaorenSplit")
    public void chaorenSplit(SpellMsg spellMsg) {
        SpellOrder spellOrder = spellOrderService.getById(spellMsg.getId());
        if(spellOrder != null){
            if(spellOrder.getIsPrivilege() == 1){
                //不中
                SpellMsg spellMsg1 = SpellMsg.builder().id(spellOrder.getId()).build();
                spellMsg1.setTraceId(MDCUtil.getTraceId());
                messageService.sendQueueByObject(AmqpExchange.SPELL_MESSAGE, spellMsg1);
            }else{
                //中
                spellOrder.setSendStatus(0);
                spellOrderService.updateById(spellOrder);
            }
        }
        /*if (oemService.isChaoRenGou()) {
            spellChaoRenHaiGou(spellMsg);
        } else {
            spellDefault(spellMsg);
        }*/
    }

    private void spellChaoRenHaiGouNew(SpellMsg spellMsg) {
        SpellOrder spellOrder = spellOrderService.getById(spellMsg.getId());
        String spellOrderId = spellOrder.getSpellOrderId();
        log.info("拼团:{} {}", spellOrder.getPriceId(), spellOrder.getSpellOrderId());
        SpellPrice spellPrice = spellPriceService.getById(spellOrder.getPriceId());
        log.info("价格区间:{} 要求成功成团人数:{} 必中人数:{}", spellPrice.getTitle(), spellPrice.getSuccessPeople(), spellPrice.getSuccessNum());
        List<SpellOrder> spellOrderList = spellOrderService.getSpellingOrder(spellOrderId, 2);
        //List<SpellOrder> spellOrderList1 = spellOrderService.getSpellingOrder(spellOrderId, 2);
        //spellOrderList.addAll(spellOrderList1);
        int failure = 0;
        int success = 0;
        /**
         * 开团条件
         * 1. 多少人数成团；
         * 2. 必中的现金支付人数；
         */
        boolean spellFlag = false;
        List<SpellOrder> updateList = new ArrayList<>();
        String ids = "|";
        for (SpellOrder spellOrder1 : spellOrderList) {
            if (spellOrder1.getIsPrivilege() == 1) { //必不中
                if(failure >= spellPrice.getSuccessPeople() - spellPrice.getSuccessNum()){
                    continue;
                }
                failure++;
                //spellOrder1.setStatus(2);
                if (failure <= spellPrice.getSuccessPeople() - spellPrice.getSuccessNum()) {
                    spellOrder1.setStatus(4);
                    updateList.add(spellOrder1);
                    ids = ids + spellOrder1.getId().toString() + "|";
                }
            } else { //必中
                if(spellOrder1.getSendStatus() == 0){
                    continue;
                }
                if(success >= spellPrice.getSuccessNum()){
                    continue;
                }
                success++;
                //spellOrder1.setStatus(2);
                if (success <= spellPrice.getSuccessNum()) {
                    spellOrder1.setStatus(3);
                    updateList.add(spellOrder1);
                    ids = ids + spellOrder1.getId().toString() + "|";
                }
            }
            if (failure >= spellPrice.getSuccessPeople() - spellPrice.getSuccessNum() && success == spellPrice.getSuccessNum()) {
                spellFlag = true;
                break;
            }
        }
        if (!spellFlag) {
            log.error("等待成团,当前成团人数：{} 必中人数：{} 不足", failure + success, success);
            return;
        }
        SpellInfo spellInfo = addSpellInfo(spellPrice.getId(), (long) failure, (long) success, spellPrice.getTitle(), spellOrderId, true);
        log.info("保存拼团信息:{}", JSON.toJSONString(spellInfo));
        spellOrderService.updateBatchById(updateList);
        log.info("更新拼团批次:{}", updateList);
        spellPrice.setNewSpellOrderId(idGeneratorService.genCommonIdString());
        spellPriceService.updateById(spellPrice);
        log.info("创建新团:{}", spellPrice.getNewSpellOrderId());
        for (SpellOrder spellOrder1 : spellOrderList){
            if(ids.indexOf(spellOrder1.getId().toString()) < 0){
                //更新新团信息
                spellOrder1.setSpellOrderId(spellPrice.getNewSpellOrderId());
                spellOrderService.updateById(spellOrder1);
            }
        }
        SpellFinishedMsg spellFinishedMsg = SpellFinishedMsg.builder()
                .spellOrderId(spellOrderId)
                .spellId(spellInfo.getId())
                .isChaoRenGou(oemService.isChaoRenGou())
                .spellPriceId(spellOrder.getPriceId()).build();
        spellFinishedMsg.setTraceId(MDC.get(LOG_TRACE_ID));
        messageService.sendQueueByObject(AmqpExchange.SPELL_FINISHED_MESSAGE, spellFinishedMsg);
        log.info("拼团完成:{}", spellOrderId);
    }
    private void spellChaoRenHaiGou(SpellMsg spellMsg) {
        SpellOrder spellOrder = spellOrderService.getById(spellMsg.getId());
        String spellOrderId = spellOrder.getSpellOrderId();
        log.info("拼团:{} {}", spellOrder.getPriceId(), spellOrder.getSpellOrderId());
        SpellInfo spellInfo = spellInfoService.getOne(Wraps.<SpellInfo>lbQ().eq(SpellInfo::getOrderNum, spellOrder.getSpellOrderId()));
        if (spellInfo != null) {
            if(spellInfo.getStatus() == 2){
                log.info("避免重复开团");
                return ;
            }
            //已经开团,判断是否所有订单都支付
            List<SpellOrder> spellOrders = spellOrderService.getSpellingOrderBySendStatus(spellOrder.getSpellOrderId(), 0);
            if (spellOrders == null || spellOrders.size() <= 0) {
                //该团已经全部支付完成，开始分红
            }else{
                log.error("未全部支付完成");
                return;
            }
            spellInfo.setStatus(2);
            spellInfoService.updateById(spellInfo);
            spellOrders = spellOrderService.getSpellingOrder(spellOrder.getSpellOrderId(), 2);
            for (SpellOrder spellOrder1 : spellOrders) {
                if (spellOrder1.getIsPrivilege() == 1) {
                    spellOrder1.setStatus(4);
                } else {
                    spellOrder1.setStatus(3);
                }
            }
            spellOrderService.updateBatchById(spellOrders);
            SpellFinishedMsg spellFinishedMsg = SpellFinishedMsg.builder()
                    .spellOrderId(spellOrderId)
                    .spellId(spellInfo.getId())
                    .isChaoRenGou(true)
                    .spellPriceId(spellOrder.getPriceId()).build();
            spellFinishedMsg.setTraceId(MDC.get(LOG_TRACE_ID));
            messageService.sendQueueByObject(AmqpExchange.SPELL_FINISHED_MESSAGE, spellFinishedMsg);
            return;
        }
        SpellPrice spellPrice = spellPriceService.getById(spellOrder.getPriceId());
        log.info("价格区间:{} 要求成功成团人数:{} 必中人数:{}", spellPrice.getTitle(), spellPrice.getSuccessPeople(), spellPrice.getSuccessNum());
        List<SpellOrder> spellOrderList = spellOrderService.getSpellingOrder(spellOrderId, 2);
        //List<SpellOrder> spellOrderList1 = spellOrderService.getSpellingOrder(spellOrderId, 2);
        //spellOrderList.addAll(spellOrderList1);
        int failure = 0;
        int success = 0;
        /**
         * 开团条件
         * 1. 多少人数成团；
         * 2. 必中的现金支付人数；
         */
        boolean spellFlag = false;
        List<SpellOrder> updateList = new ArrayList<>();
        String ids = "|";
        for (SpellOrder spellOrder1 : spellOrderList) {
            if (spellOrder1.getIsPrivilege() == 1) { //必不中
                if(failure >= spellPrice.getSuccessPeople() - spellPrice.getSuccessNum()){
                    continue;
                }
                failure++;
                //spellOrder1.setStatus(2);
                if (failure <= spellPrice.getSuccessPeople() - spellPrice.getSuccessNum()) {
                    updateList.add(spellOrder1);
                    ids = ids + spellOrder1.getId().toString() + "|";
                }
            } else { //必中
                if(success >= spellPrice.getSuccessNum()){
                    continue;
                }
                success++;
                spellOrder1.setSendStatus(0);
                //spellOrder1.setStatus(2);
                //spellOrder1.setStatus(3);
                if (success <= spellPrice.getSuccessNum()) {
                    updateList.add(spellOrder1);
                    ids = ids + spellOrder1.getId().toString() + "|";
                }
            }
            if (failure >= spellPrice.getSuccessPeople() - spellPrice.getSuccessNum() && success == spellPrice.getSuccessNum()) {
                spellFlag = true;
                break;
            }
        }
        if (!spellFlag) {
            log.error("等待成团,当前成团人数：{} 必中人数：{} 不足", failure + success, success);
            return;
        }
        spellInfo = addSpellInfo(spellPrice.getId(), (long) failure, (long) success, spellPrice.getTitle(), spellOrderId, oemService.isChaoRenGou() ? false : true);
        log.info("保存拼团信息:{}", JSON.toJSONString(spellInfo));
        spellOrderService.updateBatchById(updateList);
        log.info("更新拼团批次:{}", updateList);
        spellPrice.setNewSpellOrderId(idGeneratorService.genCommonIdString());
        spellPriceService.updateById(spellPrice);
        log.info("创建新团:{}", spellPrice.getNewSpellOrderId());
        for (SpellOrder spellOrder1 : spellOrderList){
            if(ids.indexOf(spellOrder1.getId().toString()) < 0){
                //更新新团信息
                spellOrder1.setSpellOrderId(spellPrice.getNewSpellOrderId());
                spellOrderService.updateById(spellOrder1);
            }
        }
            //spellOrderService.updateNewSpellOrderId(spellOrderId, spellPrice.getNewSpellOrderId());
        SpellFinishedMsg spellFinishedMsg = SpellFinishedMsg.builder()
                .spellOrderId(spellOrderId)
                .spellId(spellInfo.getId())
                .isChaoRenGou(oemService.isChaoRenGou())
                .spellPriceId(spellOrder.getPriceId()).build();
        spellFinishedMsg.setTraceId(MDC.get(LOG_TRACE_ID));
        messageService.sendQueueByObject(AmqpExchange.SPELL_NOTIFY_FORPAY_MESSAGE, spellFinishedMsg);
        log.info("拼团完成:{}", spellOrderId);
    }

    private void spellDefault(SpellMsg spellMsg) {
        SpellOrder spellOrder = spellOrderService.getById(spellMsg.getId());
        log.info("拼团新增一个订单：{}", spellOrder.getId());
        String spellOrderId = spellOrder.getSpellOrderId();
        log.info("拼团:{} {}", spellOrder.getPriceId(), spellOrder.getSpellOrderId());
        SpellPrice spellPrice = spellPriceService.getById(spellOrder.getPriceId());
        log.info("价格区间:{} 要求成功成团人数:{} 必中人数:{}", spellPrice.getTitle(), spellPrice.getSuccessPeople(), spellPrice.getSuccessNum());
        List<SpellOrder> spellOrderList = spellOrderService.getSpellingOrder(spellOrderId, 2);
        int failure = 0;
        int success = 0;
        /**
         * 开团条件
         * 1. 多少人数成团；
         * 2. 必中的现金支付人数；
         */
        boolean spellFlag = false;
        List<SpellOrder> updateList = new ArrayList<>();
        for (SpellOrder spellOrder1 : spellOrderList) {
            if (spellOrder1.getIsPrivilege() == 1) { //必不中
                failure++;
                spellOrder1.setStatus(4);
                if (failure <= spellPrice.getSuccessPeople() - spellPrice.getSuccessNum()) {
                    updateList.add(spellOrder1);
                }
            } else { //必中
                if(success >= spellPrice.getSuccessNum()){
                    continue;
                }
                success++;
                spellOrder1.setStatus(3);
                if (success <= spellPrice.getSuccessNum()) {
                    updateList.add(spellOrder1);
                }
            }
            if (failure >= spellPrice.getSuccessPeople() - spellPrice.getSuccessNum() && success == spellPrice.getSuccessNum()) {
                spellFlag = true;
                break;
            }
        }
        if(!spellFlag){
            updateList = new ArrayList<>();
            int success1 = 0;
            int failure1 = 0;
            //查找不到情况下，查询所有必中用户，是否满足所有的订单
            spellOrderList = spellOrderService.getSpellingOrderIsPrivilege(spellOrderId, 2);
            if(spellOrderList.size() >= spellPrice.getSuccessPeople()){
                for (SpellOrder spellOrder1 : spellOrderList) {
                    if(success1 <  spellPrice.getSuccessNum()){
                        success1 ++;
                        spellOrder1.setStatus(3);
                        updateList.add(spellOrder1);
                    }else{
                        failure1 ++;
                        spellOrder1.setStatus(4);
                        updateList.add(spellOrder1);
                    }
                    if(failure1 + success1 >= spellPrice.getSuccessPeople()){
                        spellFlag = true;
                        break;
                    }
                }
            }

        }
        if (!spellFlag) {
            log.error("等待成团,当前成团人数：{} 必中人数：{} 不足", failure + success, success);
            return;
        }
        SpellInfo spellInfo = addSpellInfo(spellPrice.getId(), (long) failure, (long) success, spellPrice.getTitle(), spellOrderId, oemService.isChaoRenGou() ? false : true);
        log.info("保存拼团信息:{}", JSON.toJSONString(spellInfo));
        spellOrderService.updateBatchById(updateList);
        log.info("更新拼团批次:{}", updateList);
        spellPrice.setNewSpellOrderId(idGeneratorService.genCommonIdString());
        spellPriceService.updateById(spellPrice);
        log.info("创建新团:{}", spellPrice.getNewSpellOrderId());
        spellOrderService.updateNewSpellOrderId(spellOrderId, spellPrice.getNewSpellOrderId());
        SpellFinishedMsg spellFinishedMsg = SpellFinishedMsg.builder()
                .spellOrderId(spellOrderId)
                .spellId(spellInfo.getId())
                .isChaoRenGou(oemService.isChaoRenGou())
                .spellPriceId(spellOrder.getPriceId()).build();
        spellFinishedMsg.setTraceId(MDC.get(LOG_TRACE_ID));
        messageService.sendQueueByObject(AmqpExchange.SPELL_FINISHED_MESSAGE, spellFinishedMsg);
        log.info("拼团完成:{}", spellOrderId);
    }

    private SpellInfo addSpellInfo(Long priceId, Long failure, Long success, String title, String spellOrderId, Boolean isSuccess) {
        SpellInfo spellInfo = new SpellInfo();
        spellInfo.setPriceId(priceId);
        spellInfo.setStatus(isSuccess ? 2 : 1);
        spellInfo.setFailureCount(failure);
        spellInfo.setSuccessCount(success);
        spellInfo.setPriceTitle(title);
        spellInfo.setOrderNum(spellOrderId);
        spellInfo.setLoveVlue(0L);
        spellInfo.setContributionValue(0L);
        spellInfo.setSpellValue(0L);
        spellInfo.setShareValue(0L);
        spellInfo.setSplitValue(0L);
        spellInfo.setSmallValue(0L);
        spellInfo.setCenterSplitValue(0L);
        spellInfo.setCenterSmallValue(0L);
        spellInfo.setSettDate(SystemClockUtil.getSettDateyyyyMMdd());
        spellInfoService.save(spellInfo);
        return spellInfo;
    }
}
